<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="Hugo 0.98.0" />

  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="author" content="" />
  <meta property="og:url" content="/posts/c%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97/%E5%85%A5%E9%97%A8%E6%96%87%E6%9C%AC%E6%B5%81%E6%A8%A1%E5%9E%8B%E4%B8%8E%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C/" />
  <link rel="canonical" href="/posts/c%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97/%E5%85%A5%E9%97%A8%E6%96%87%E6%9C%AC%E6%B5%81%E6%A8%A1%E5%9E%8B%E4%B8%8E%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C/" /><link rel="alternate" type="application/atom+xml" href="/index.xml" title="信息管理实验室">

  <script type="application/ld+json">
  {
      "@context" : "http://schema.org",
      "@type" : "BlogPosting",
      "mainEntityOfPage": {
           "@type": "WebPage",
           "@id": "\/"
      },
      "articleSection" : "posts",
      "name" : "入门：文本流模型与文件操作",
      "headline" : "入门：文本流模型与文件操作",
      "description" : "文本流的本质就是二进制数据流，其表现的形式，就是一维的字符数组。\n文本流工作的流程如下：\n 设备将二进制数据送到缓冲区 文本流将二进制数据进行转化，主要为： 按照 \u0026lsquo;\\n\u0026rsquo; 符号，将二进制流解析为一行行文本 最后输入\\输出函数按照一行行文本进行读写  \/* stream_first.c Use the stream to solve the problem BeginnerC *\/ #include \u0026lt;stdio.h\u0026gt;int main() {  char c = \u0026#39;c\u0026#39;;  char read_char = \u0026#39;n\u0026#39;;  ungetc(read_char, stdin);  c = getchar();  putchar(c);  return 0; } 在这个案例中，我们展现了文本流模型的冰山一角，如您所见，getchar 函数直接返回了 \u0026rsquo;n\u0026rsquo;，而在这之前，我们使用了一个新函数 ungetc 将 \u0026rsquo;n\u0026rsquo; 写入 stdin。\n下面，我们叙述这一切的工作原理。\n在 C语言 中，所有标准库函数的输入输出，都扎根于文本流模型，而 C语言 在运行的时候，默认也提供三个文本流供我们读写数据。\n他们分别的 stdin, stdout, stderr，其中 前缀 std 代表 “标准\u0026quot;，而in, out, err 代表输入、输出与错误。",
      "inLanguage" : "en-US",
      "author" : "",
      "creator" : "",
      "publisher": "",
      "accountablePerson" : "",
      "copyrightHolder" : "",
      "copyrightYear" : "2023",
      "datePublished": "2023-01-30 00:00:00 \u002b0000 UTC",
      "dateModified" : "2023-01-30 00:00:00 \u002b0000 UTC",
      "url" : "\/posts\/c%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97\/%E5%85%A5%E9%97%A8%E6%96%87%E6%9C%AC%E6%B5%81%E6%A8%A1%E5%9E%8B%E4%B8%8E%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C\/",
      "keywords" : [ "C语言入门指南","C语言","信息管理实验室", ]
  }
</script>
<title>入门：文本流模型与文件操作</title>
  <meta property="og:title" content="入门：文本流模型与文件操作" />
  <meta property="og:type" content="article" />
  <meta property="og:description" content="文本流的本质就是二进制数据流，其表现的形式，就是一维的字符数组。
文本流工作的流程如下：
 设备将二进制数据送到缓冲区 文本流将二进制数据进行转化，主要为： 按照 &amp;lsquo;\n&amp;rsquo; 符号，将二进制流解析为一行行文本 最后输入\输出函数按照一行行文本进行读写  /* stream_first.c Use the stream to solve the problem BeginnerC */ #include &amp;lt;stdio.h&amp;gt;int main() {  char c = &amp;#39;c&amp;#39;;  char read_char = &amp;#39;n&amp;#39;;  ungetc(read_char, stdin);  c = getchar();  putchar(c);  return 0; } 在这个案例中，我们展现了文本流模型的冰山一角，如您所见，getchar 函数直接返回了 &amp;rsquo;n&amp;rsquo;，而在这之前，我们使用了一个新函数 ungetc 将 &amp;rsquo;n&amp;rsquo; 写入 stdin。
下面，我们叙述这一切的工作原理。
在 C语言 中，所有标准库函数的输入输出，都扎根于文本流模型，而 C语言 在运行的时候，默认也提供三个文本流供我们读写数据。
他们分别的 stdin, stdout, stderr，其中 前缀 std 代表 “标准&amp;quot;，而in, out, err 代表输入、输出与错误。" />
  <meta name="description" content="文本流的本质就是二进制数据流，其表现的形式，就是一维的字符数组。
文本流工作的流程如下：
 设备将二进制数据送到缓冲区 文本流将二进制数据进行转化，主要为： 按照 &amp;lsquo;\n&amp;rsquo; 符号，将二进制流解析为一行行文本 最后输入\输出函数按照一行行文本进行读写  /* stream_first.c Use the stream to solve the problem BeginnerC */ #include &amp;lt;stdio.h&amp;gt;int main() {  char c = &amp;#39;c&amp;#39;;  char read_char = &amp;#39;n&amp;#39;;  ungetc(read_char, stdin);  c = getchar();  putchar(c);  return 0; } 在这个案例中，我们展现了文本流模型的冰山一角，如您所见，getchar 函数直接返回了 &amp;rsquo;n&amp;rsquo;，而在这之前，我们使用了一个新函数 ungetc 将 &amp;rsquo;n&amp;rsquo; 写入 stdin。
下面，我们叙述这一切的工作原理。
在 C语言 中，所有标准库函数的输入输出，都扎根于文本流模型，而 C语言 在运行的时候，默认也提供三个文本流供我们读写数据。
他们分别的 stdin, stdout, stderr，其中 前缀 std 代表 “标准&amp;quot;，而in, out, err 代表输入、输出与错误。" />
  <meta property="og:locale" content="zh-cn" /><meta property="og:image" content="" />
  

  
    <style>body{font-family:bree serif,sans-serif;-webkit-font-smoothing:antialiased;margin:0 20px}article{max-width:800px;margin-left:auto;margin-right:auto}a{color:#000;text-decoration:none}a:hover{font-weight:600;text-decoration:underline}.post-ads{margin:50px 0}.markdown-body{font-size:18px;max-width:100%}.markdown-body a{text-decoration:underline;text-decoration-color:#000}.markdown-body blockquote{margin:0;padding:0 1em;color:#57606a;border-left:.25em solid #d0d7de}.markdown-body pre{padding:16px;overflow:auto;border-radius:10px}.markdown-body code{padding:.2em .4em;font-size:85%;background-color:#f6f8fa;border-radius:6px}.markdown-body pre>code{padding:0;font-size:100%;background-color:inherit;border:0}.Chinese .markdown-body{line-height:200%}.site-date-catalog{font-size:2rem}.header-title{font-size:2rem;font-weight:700;margin-top:32px;font-family:bungee shade,sans-serif}.header-title a{text-decoration:none}.header-subtitle{color:#666}.header-items{margin:10px 0}.header-item{margin:0 5px}.header-line{width:100%;border-width:2px;border-color:#482936;border-style:solid none none none}.lang-switch{font-weight:600}#posts-list{min-height:600px}.posts-line{font-size:1.2rem;margin:12px 0}.posts-categories{font-size:.8rem;margin:auto;text-align:center}.posts-category{padding:3px 0;border:#000 2px solid;border-radius:5px}.site-footer{margin-top:50px}.site-footer-item{margin-right:12px}.post-content img{max-width:100%;display:block;margin-right:auto;margin-top:12px}.post-header{margin-bottom:50px}.post-title{font-size:2rem;font-weight:600}.post-tags{display:inline-block;font-weight:600;padding:2px 5px;margin-right:6px;margin-top:4px;border:#000 2px solid;border-radius:5px}.post-date{font-weight:800;font-style:italic}.post-author{float:right;font-weight:600}.page-content{min-height:60%}.post-content{margin-bottom:50px}.post-content p{hyphens:auto;line-height:1.8;text-justify:ideographic;margin-bottom:1em}.related-content{border-width:3px;border-style:solid;border-color:#000;padding:0 10px;margin-bottom:50px;margin-top:100px}.related-content li{margin:5px 0}.taxonomy-term{font-size:3rem}.gallery-img{text-align:center}.gallery-img span{text-align:center}.gallery-img-desc{font-size:.8em;font-weight:800}@media screen and (max-width:600px){.header-title,.header-subtitle,.header-items{text-align:center}.posts-line{font-size:16px}.markdown-body{font-size:16px}.post-title{font-size:2rem}.post-content p{letter-spacing:.05em}}@media screen and (max-width:48em){.posts-category{display:none}}</style>
  
  
    <style>.container,.container-fluid{margin-right:auto;margin-left:auto}.container-fluid{padding-right:2rem;padding-left:2rem}.row{box-sizing:border-box;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:initial;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-.5rem;margin-left:-.5rem}.row.reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.col.reverse{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.col-xs,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-offset-0,.col-xs-offset-1,.col-xs-offset-10,.col-xs-offset-11,.col-xs-offset-12,.col-xs-offset-2,.col-xs-offset-3,.col-xs-offset-4,.col-xs-offset-5,.col-xs-offset-6,.col-xs-offset-7,.col-xs-offset-8,.col-xs-offset-9{box-sizing:border-box;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:none;padding-right:.5rem;padding-left:.5rem}.col-xs{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-preferred-size:0;flex-basis:0;max-width:100%}.col-xs-1{-ms-flex-preferred-size:8.33333333%;flex-basis:8.33333333%;max-width:8.33333333%}.col-xs-2{-ms-flex-preferred-size:16.66666667%;flex-basis:16.66666667%;max-width:16.66666667%}.col-xs-3{-ms-flex-preferred-size:25%;flex-basis:25%;max-width:25%}.col-xs-4{-ms-flex-preferred-size:33.33333333%;flex-basis:33.33333333%;max-width:33.33333333%}.col-xs-5{-ms-flex-preferred-size:41.66666667%;flex-basis:41.66666667%;max-width:41.66666667%}.col-xs-6{-ms-flex-preferred-size:50%;flex-basis:50%;max-width:50%}.col-xs-7{-ms-flex-preferred-size:58.33333333%;flex-basis:58.33333333%;max-width:58.33333333%}.col-xs-8{-ms-flex-preferred-size:66.66666667%;flex-basis:66.66666667%;max-width:66.66666667%}.col-xs-9{-ms-flex-preferred-size:75%;flex-basis:75%;max-width:75%}.col-xs-10{-ms-flex-preferred-size:83.33333333%;flex-basis:83.33333333%;max-width:83.33333333%}.col-xs-11{-ms-flex-preferred-size:91.66666667%;flex-basis:91.66666667%;max-width:91.66666667%}.col-xs-12{-ms-flex-preferred-size:100%;flex-basis:100%;max-width:100%}.col-xs-offset-0{margin-left:0}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-11{margin-left:91.66666667%}.start-xs{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;text-align:start}.center-xs{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;text-align:center}.end-xs{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;text-align:end}.top-xs{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.middle-xs{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.bottom-xs{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.around-xs{-ms-flex-pack:distribute;justify-content:space-around}.between-xs{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.first-xs{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.last-xs{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}@media only screen and (min-width:48em){.container{width:49rem}.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-offset-0,.col-sm-offset-1,.col-sm-offset-10,.col-sm-offset-11,.col-sm-offset-12,.col-sm-offset-2,.col-sm-offset-3,.col-sm-offset-4,.col-sm-offset-5,.col-sm-offset-6,.col-sm-offset-7,.col-sm-offset-8,.col-sm-offset-9{box-sizing:border-box;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:none;padding-right:.5rem;padding-left:.5rem}.col-sm{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-preferred-size:0;flex-basis:0;max-width:100%}.col-sm-1{-ms-flex-preferred-size:8.33333333%;flex-basis:8.33333333%;max-width:8.33333333%}.col-sm-2{-ms-flex-preferred-size:16.66666667%;flex-basis:16.66666667%;max-width:16.66666667%}.col-sm-3{-ms-flex-preferred-size:25%;flex-basis:25%;max-width:25%}.col-sm-4{-ms-flex-preferred-size:33.33333333%;flex-basis:33.33333333%;max-width:33.33333333%}.col-sm-5{-ms-flex-preferred-size:41.66666667%;flex-basis:41.66666667%;max-width:41.66666667%}.col-sm-6{-ms-flex-preferred-size:50%;flex-basis:50%;max-width:50%}.col-sm-7{-ms-flex-preferred-size:58.33333333%;flex-basis:58.33333333%;max-width:58.33333333%}.col-sm-8{-ms-flex-preferred-size:66.66666667%;flex-basis:66.66666667%;max-width:66.66666667%}.col-sm-9{-ms-flex-preferred-size:75%;flex-basis:75%;max-width:75%}.col-sm-10{-ms-flex-preferred-size:83.33333333%;flex-basis:83.33333333%;max-width:83.33333333%}.col-sm-11{-ms-flex-preferred-size:91.66666667%;flex-basis:91.66666667%;max-width:91.66666667%}.col-sm-12{-ms-flex-preferred-size:100%;flex-basis:100%;max-width:100%}.col-sm-offset-0{margin-left:0}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-11{margin-left:91.66666667%}.start-sm{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;text-align:start}.center-sm{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;text-align:center}.end-sm{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;text-align:end}.top-sm{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.middle-sm{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.bottom-sm{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.around-sm{-ms-flex-pack:distribute;justify-content:space-around}.between-sm{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.first-sm{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.last-sm{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}}@media only screen and (min-width:64em){.container{width:65rem}.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-offset-0,.col-md-offset-1,.col-md-offset-10,.col-md-offset-11,.col-md-offset-12,.col-md-offset-2,.col-md-offset-3,.col-md-offset-4,.col-md-offset-5,.col-md-offset-6,.col-md-offset-7,.col-md-offset-8,.col-md-offset-9{box-sizing:border-box;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:none;padding-right:.5rem;padding-left:.5rem}.col-md{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-preferred-size:0;flex-basis:0;max-width:100%}.col-md-1{-ms-flex-preferred-size:8.33333333%;flex-basis:8.33333333%;max-width:8.33333333%}.col-md-2{-ms-flex-preferred-size:16.66666667%;flex-basis:16.66666667%;max-width:16.66666667%}.col-md-3{-ms-flex-preferred-size:25%;flex-basis:25%;max-width:25%}.col-md-4{-ms-flex-preferred-size:33.33333333%;flex-basis:33.33333333%;max-width:33.33333333%}.col-md-5{-ms-flex-preferred-size:41.66666667%;flex-basis:41.66666667%;max-width:41.66666667%}.col-md-6{-ms-flex-preferred-size:50%;flex-basis:50%;max-width:50%}.col-md-7{-ms-flex-preferred-size:58.33333333%;flex-basis:58.33333333%;max-width:58.33333333%}.col-md-8{-ms-flex-preferred-size:66.66666667%;flex-basis:66.66666667%;max-width:66.66666667%}.col-md-9{-ms-flex-preferred-size:75%;flex-basis:75%;max-width:75%}.col-md-10{-ms-flex-preferred-size:83.33333333%;flex-basis:83.33333333%;max-width:83.33333333%}.col-md-11{-ms-flex-preferred-size:91.66666667%;flex-basis:91.66666667%;max-width:91.66666667%}.col-md-12{-ms-flex-preferred-size:100%;flex-basis:100%;max-width:100%}.col-md-offset-0{margin-left:0}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-3{margin-left:25%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-6{margin-left:50%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-9{margin-left:75%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-11{margin-left:91.66666667%}.start-md{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;text-align:start}.center-md{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;text-align:center}.end-md{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;text-align:end}.top-md{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.middle-md{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.bottom-md{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.around-md{-ms-flex-pack:distribute;justify-content:space-around}.between-md{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.first-md{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.last-md{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}}@media only screen and (min-width:75em){.container{width:76rem}.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-offset-0,.col-lg-offset-1,.col-lg-offset-10,.col-lg-offset-11,.col-lg-offset-12,.col-lg-offset-2,.col-lg-offset-3,.col-lg-offset-4,.col-lg-offset-5,.col-lg-offset-6,.col-lg-offset-7,.col-lg-offset-8,.col-lg-offset-9{box-sizing:border-box;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:none;padding-right:.5rem;padding-left:.5rem}.col-lg{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-preferred-size:0;flex-basis:0;max-width:100%}.col-lg-1{-ms-flex-preferred-size:8.33333333%;flex-basis:8.33333333%;max-width:8.33333333%}.col-lg-2{-ms-flex-preferred-size:16.66666667%;flex-basis:16.66666667%;max-width:16.66666667%}.col-lg-3{-ms-flex-preferred-size:25%;flex-basis:25%;max-width:25%}.col-lg-4{-ms-flex-preferred-size:33.33333333%;flex-basis:33.33333333%;max-width:33.33333333%}.col-lg-5{-ms-flex-preferred-size:41.66666667%;flex-basis:41.66666667%;max-width:41.66666667%}.col-lg-6{-ms-flex-preferred-size:50%;flex-basis:50%;max-width:50%}.col-lg-7{-ms-flex-preferred-size:58.33333333%;flex-basis:58.33333333%;max-width:58.33333333%}.col-lg-8{-ms-flex-preferred-size:66.66666667%;flex-basis:66.66666667%;max-width:66.66666667%}.col-lg-9{-ms-flex-preferred-size:75%;flex-basis:75%;max-width:75%}.col-lg-10{-ms-flex-preferred-size:83.33333333%;flex-basis:83.33333333%;max-width:83.33333333%}.col-lg-11{-ms-flex-preferred-size:91.66666667%;flex-basis:91.66666667%;max-width:91.66666667%}.col-lg-12{-ms-flex-preferred-size:100%;flex-basis:100%;max-width:100%}.col-lg-offset-0{margin-left:0}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-11{margin-left:91.66666667%}.start-lg{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;text-align:start}.center-lg{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;text-align:center}.end-lg{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;text-align:end}.top-lg{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.middle-lg{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.bottom-lg{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.around-lg{-ms-flex-pack:distribute;justify-content:space-around}.between-lg{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.first-lg{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.last-lg{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}}</style>
  

  

  <link href="/index.xml" rel="alternate" type="application/rss+xml"
    title="信息管理实验室">
  
  <link rel="preconnect" href="https://fonts.gstatic.com">
  <link href="https://fonts.googleapis.com/css?family=Bree+Serif|Bungee+Shade" rel="stylesheet">
  
  

  
  
</head>


<body>
  <article class="post " id="article">
    <div class="row">
      <div class="col-xs-12">
        <div class="site-header">
          
<header>
  <div class="header-title">
    <a href="/"
      >信息管理实验室</a
    >
  </div>
  <div class="header-subtitle"></div>
</header>
<div class="row end-md center-xs header-items">
  
  <div class="header-item">
    <a href="/posts/%e4%bd%a0%e5%a5%bd%e6%9c%8b%e5%8f%8b/" target="_blank">About</a>
  </div>
  
  <div class="header-item">
    <a href="/tags/%e6%88%91%e4%bb%ac%e7%9a%84%e4%bc%99%e4%bc%b4/" target="_blank">Friends</a>
  </div>
  
  <div class="header-item">
    <a href="/tags/%e7%a4%be%e5%8c%ba%e4%b9%a6%e7%b1%8d/" target="_blank">Books</a>
  </div>
  
</div>
<div class="row end-xs">
   
</div>
<div class="header-line"></div>

        </div>
        <header class="post-header">
          <h1 class="post-title">入门：文本流模型与文件操作</h1>
          
          <div class="row post-desc">
            <div class="col-xs-6">
              
              <time class="post-date">
                2023-01-30
              </time>
              
              
              <br>
            </div>
          </div>
          <div class="row end-xs">
            
              <a href="/author/%e6%95%ac%e7%ab%a0/"><strong>&nbsp;@敬章</strong></a>        
            
          </div>
          
        </header>

        <div class="post-content markdown-body">
          
          <p>文本流的本质就是二进制数据流，其表现的形式，就是一维的字符数组。</p>
<p><img src="image/%E6%96%87%E6%9C%AC%E6%B5%81%E4%B8%8E%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C/1673391825151.png" alt="1673391825151"></p>
<p>文本流工作的流程如下：</p>
<ol>
<li>设备将二进制数据送到缓冲区</li>
<li>文本流将二进制数据进行转化，主要为：
按照 &lsquo;\n&rsquo; 符号，将二进制流解析为一行行文本</li>
<li>最后输入\输出函数按照一行行文本进行读写</li>
</ol>
<p><img src="image/%E6%96%87%E6%9C%AC%E6%B5%81%E4%B8%8E%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C/1673392023656.png" alt="1673392023656"></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">/*
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    stream_first.c
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    Use the stream to solve the problem
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    BeginnerC
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">*/</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&lt;stdio.h&gt;</span><span style="color:#75715e">
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">char</span> c <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;c&#39;</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">char</span> read_char <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;n&#39;</span>;
</span></span><span style="display:flex;"><span>    ungetc(read_char, stdin);
</span></span><span style="display:flex;"><span>    c <span style="color:#f92672">=</span> getchar();
</span></span><span style="display:flex;"><span>    putchar(c);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">0</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>在这个案例中，我们展现了文本流模型的冰山一角，如您所见，getchar 函数直接返回了 &rsquo;n&rsquo;，而在这之前，我们使用了一个新函数 ungetc 将 &rsquo;n&rsquo; 写入 stdin。</p>
<p>下面，我们叙述这一切的工作原理。</p>
<p>在 C语言 中，所有标准库函数的输入输出，都扎根于文本流模型，而 C语言 在运行的时候，默认也提供三个文本流供我们读写数据。</p>
<p>他们分别的 stdin, stdout, stderr，其中 前缀 std 代表 “标准&quot;，而in, out, err 代表输入、输出与错误。</p>
<p>他们的抽象就是字符数组，而在刚刚的工作流程之中：</p>
<ol>
<li>一开始，标准输入输出流没有任何数据</li>
<li>使用 ungetc 以后，标准输入流里面拥有了字符 &rsquo;n&rsquo;</li>
<li>使用 getchar 函数以后，我们从标准输入流中读入了字符 &rsquo;n'</li>
</ol>
<p>值得一提的是，ungetc 的原理是对输入流缓冲区进行操作，而如果我们对输出流进行操作，其结果是未定义的。</p>
<p><img src="image/%E6%96%87%E6%9C%AC%E6%B5%81%E4%B8%8E%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C/1673404786182.png" alt="1673404786182"></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">/*
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    stream_second.c
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    Use the stream to solve the problem
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    BeginnerC
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">*/</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&lt;stdio.h&gt;</span><span style="color:#75715e">
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">char</span> c <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;\0&#39;</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">while</span> (EOF <span style="color:#f92672">!=</span> (c <span style="color:#f92672">=</span> getchar()))
</span></span><span style="display:flex;"><span>        putchar(c);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">0</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>在这个程序中，我们将输入流复制到输出流之中，我们可以发现：尽管 getchar 只读取一个字符，但是它真正工作起来是在我们换行之后。</p>
<p>这就体现出文本流模型按行读取的特点。</p>
<p>事实上，这个程序等价于</p>
<p><img src="image/%E6%96%87%E6%9C%AC%E6%B5%81%E4%B8%8E%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C/1673406174465.png" alt="1673406174465"></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">/*
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    stream_third.c
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    Use the stream to solve the problem
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    BeginnerC
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">*/</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&lt;stdio.h&gt;</span><span style="color:#75715e">
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">char</span> c <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;\0&#39;</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">while</span> (EOF <span style="color:#f92672">!=</span> (c <span style="color:#f92672">=</span> getc(stdin)))
</span></span><span style="display:flex;"><span>        putc(c, stdout);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">0</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>事实上，很多 C语言标准库函数 都是对输入输出流做了一层封装。</p>
<p>包括 printf, scanf 这些我们打过许多次交道的程序。</p>
<p>现在，我们发现程序中多出了一个叫做 <code>EOF</code> 的常量，它的含义就是“流结束&quot;。，在 Fedora Linux 下面，CTRL+D可以让输入流结束。</p>
<p>而现在，我们希望以另一种角度看待文本流，那就是普通文件的角度。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-plaintext" data-lang="plaintext"><span style="display:flex;"><span>Hello World
</span></span><span style="display:flex;"><span>Here is BeginnerC
</span></span></code></pre></div><p>如你所见，我们准备一段文本，并将其写入一个文本文件，并进行如图所示的操作。</p>
<p><img src="image/%E6%96%87%E6%9C%AC%E6%B5%81%E4%B8%8E%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C/1673424657712.png" alt="1673424657712"></p>
<p>在这个案例之中，我们首次展现了文件与文本流的关系，这个 <code>&lt;</code> 指令，被称为重定向，意义在于将输入的源头，从 shell 转移到 文件之中。</p>
<p>对于 C语言 而言，这仅仅意味着读写设备的转变，而不是输入输出流的改变，因此，一切照旧。</p>
<p>事实上，除了运用外部的手段以外，C语言自身也提供了许多与文件有关的函数，用于帮助我们将文本流与文件挂钩。</p>
<p><img src="image/%E6%96%87%E6%9C%AC%E6%B5%81%E4%B8%8E%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C/1673425131961.png" alt="1673425131961"></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">/*
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    freopen.c
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    Use the freopen function
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    BeginnerC
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">*/</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&lt;stdio.h&gt;</span><span style="color:#75715e">
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">char</span> c <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;\0&#39;</span>;
</span></span><span style="display:flex;"><span>    freopen(<span style="color:#e6db74">&#34;output.txt&#34;</span>, <span style="color:#e6db74">&#34;w&#34;</span>, stdout);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">while</span> (EOF <span style="color:#f92672">!=</span> (c <span style="color:#f92672">=</span> getchar()))
</span></span><span style="display:flex;"><span>        putchar(c);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">0</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>在这个程序中，我们使用 <code>freopen</code> 函数对输入输出流进行重定向，将输出流 stdout 重定向到文本文件 output.txt 中。</p>
<p>值的注意的是，这里我们首次使用了 C语言 中的文件读写字符串，下面让我们来正式罗列他们。</p>
<table>
<thead>
<tr>
<th>标志</th>
<th>含义</th>
</tr>
</thead>
<tbody>
<tr>
<td>w</td>
<td>写（如果原文件存在内容，则清空文件）</td>
</tr>
<tr>
<td>r</td>
<td>读文件（如果文件不存在，失败）</td>
</tr>
<tr>
<td>a</td>
<td>追加写模式（不存在则创建，存在则在文件末尾追加）</td>
</tr>
<tr>
<td>w+</td>
<td>读写一体（如果原文件存在内容，则清空文件）</td>
</tr>
<tr>
<td>r+</td>
<td>读写文件一体（如果文件不存在，失败）</td>
</tr>
<tr>
<td>a+</td>
<td>追加读写模式（不存在则创建，存在则在文件末尾追加）</td>
</tr>
<tr>
<td>b</td>
<td>采用二进制流模型而不是文本流（在 UNIX 下，二进制流与文本流是一体两面）</td>
</tr>
</tbody>
</table>
<p>而在这个基础上，我们也引入除“重定向&quot;以外的另一种使用文本流的方式。</p>
<p><img src="image/%E6%96%87%E6%9C%AC%E6%B5%81%E4%B8%8E%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C/1673425872863.png" alt="1673425872863"></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">/*
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    fopen.c
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    Use the fopen to open the file
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    BeginnerC
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">*/</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&lt;stdio.h&gt;</span><span style="color:#75715e">
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    FILE <span style="color:#f92672">*</span>fp <span style="color:#f92672">=</span> NULL;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> number_1, number_2, number_result;
</span></span><span style="display:flex;"><span>    fp <span style="color:#f92672">=</span> fopen(<span style="color:#e6db74">&#34;new.txt&#34;</span>, <span style="color:#e6db74">&#34;w+&#34;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> (NULL <span style="color:#f92672">==</span> fp)
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#f92672">-</span><span style="color:#ae81ff">1</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    fprintf(fp, <span style="color:#e6db74">&#34;%d + %d = %d</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">&#34;</span>, <span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span> <span style="color:#f92672">+</span> <span style="color:#ae81ff">2</span>);
</span></span><span style="display:flex;"><span>    fflush(fp);
</span></span><span style="display:flex;"><span>    fseek(fp, SEEK_SET, <span style="color:#ae81ff">0</span>);
</span></span><span style="display:flex;"><span>    fscanf(fp, <span style="color:#e6db74">&#34;%d + %d = %d&#34;</span>, <span style="color:#f92672">&amp;</span>number_1, <span style="color:#f92672">&amp;</span>number_2, <span style="color:#f92672">&amp;</span>number_result);
</span></span><span style="display:flex;"><span>    printf(<span style="color:#e6db74">&#34;%d + %d = %d</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">&#34;</span>, number_1, number_2, number_result);
</span></span><span style="display:flex;"><span>    fclose(fp);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">0</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>在这个案例中，我们使用 fprintf 与 fscanf 等函数，对文本流进行读写，fopen 则让文本流与特定的文件挂钩。</p>
<p>可以注意到，实际上：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span>printf(argument_list)
</span></span><span style="display:flex;"><span>scanf(argument_list)
</span></span><span style="display:flex;"><span><span style="color:#75715e">// Euqal to
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>fprintf(stdout, arguemnt_list)
</span></span><span style="display:flex;"><span>fscanf(stdin, argument_list)
</span></span></code></pre></div><p>而 fflush 函数，则是一个类似于“加速器&quot;的函数，它会让输出流缓冲区的内容立刻写入对应的文件。</p>
<p>值得注意的是 fseek 函数，它的职责是定位，负责读写位置在文本流中的定位。</p>
<p>其中分为</p>
<table>
<thead>
<tr>
<th>标志</th>
<th>含义</th>
</tr>
</thead>
<tbody>
<tr>
<td>SEEK_SET</td>
<td>文本流缓冲区起始</td>
</tr>
<tr>
<td>SEEK_CUR</td>
<td>文本流缓冲区当下位置</td>
</tr>
<tr>
<td>SEEK_END</td>
<td>文本流缓冲区末尾</td>
</tr>
</tbody>
</table>

        </div>

        <div class="row middle-xs">
          <div class="col-xs-12">
            
            <div class="post-tags">
              <a href="/tags/c%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97/">
                C语言入门指南
              </a>
            </div>
            
            <div class="post-tags">
              <a href="/tags/c%E8%AF%AD%E8%A8%80/">
                C语言
              </a>
            </div>
            
            <div class="post-tags">
              <a href="/tags/%E4%BF%A1%E6%81%AF%E7%AE%A1%E7%90%86%E5%AE%9E%E9%AA%8C%E5%AE%A4/">
                信息管理实验室
              </a>
            </div>
            
          </div>
        </div>
        
          <div class="row">
            <div class="col-xs-12">
              
            </div>
          </div>

          

<div class="related-content">
  <h3>Related Posts</h3>
  <ul>
    
    <li><a href="/posts/c%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97/%E5%85%A5%E9%97%A8c%E8%AF%AD%E8%A8%80%E4%B8%AD%E7%9A%84%E9%80%BB%E8%BE%91%E4%B8%8E%E5%BE%AA%E7%8E%AF/">入门：C语言中的逻辑与循环</a></li>
    
    <li><a href="/posts/c%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97/%E5%85%A5%E9%97%A8%E5%87%BD%E6%95%B0/">入门：函数</a></li>
    
    <li><a href="/posts/c%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97/%E5%85%A5%E9%97%A8%E5%8F%98%E9%87%8F/">入门：变量</a></li>
    
  </ul>

</div>


          
          
          <div style="height: 50px;"></div>
          
        

        <div class="site-footer">
  
  
</div>

      </div>
    </div>
  </article>

  

<script>
  
  
    
    
  
</script>

  

</body>

</html>